---
id: k6
title: Performance and Trace-Based Tests with Tracetest and k6
description: Quickstart on how to use the Tracetest k6 Integration to enhance Performance Tests with Trace-Based Testing using Tracetest.
hide_table_of_contents: false
keywords:
  - tracetest
  - trace-based testing
  - observability
  - distributed tracing
  - testing
  - k6
  - xk6
  - load testing
  - performance testing
image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';

:::note
[Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-k6)
:::

[Tracetest](https://app.tracetest.io/) is a testing tool based on [OpenTelemetry](https://opentelemetry.io/) that allows you to test your distributed application. It allows you to use data from distributed traces generated by OpenTelemetry to validate and assert if your application has the desired behavior defined by your test definitions.

[k6](https://k6.io/) is an open-source performance testing tool used for testing the performance of APIs, microservices, and websites. It is designed to be developer-centric, making it easy for developers to write and maintain performance tests as code.

## Why is this important?

k6 is it's a great tool in its own right that allows you to replicate most of the production challenges you might encounter. But, as with all of the tools that only test the initial transaction between the client side and the server, you can only run validations against the immediate response from the service.

<div style={{ position: "relative", paddingBottom: "62.5%", height: "0" }}>
  <iframe
    src="https://www.loom.com/embed/5c5e1261bb0b4fefa30081294378908c"
    frameborder="0"
    webkitallowfullscreen
    mozallowfullscreen
    allowfullscreen
    width="100%"
    style={{ position: "absolute", top: "0", left: "0", width: "100%", height: "100%" }}
  ></iframe>
</div>

## The k6 Tracetest Extension

With the [k6 Tracetest extension](https://github.com/kubeshop/xk6-tracetest), you will unlock the power of OpenTelemetry that allows you to run deeper testing based on the traces and spans generated by each of the checkpoints that you define within your services.

Language and Vendor agnostic, with this extension you can use your existing Tracing Data Store and Setup to leverage the work you have already done to instrument your services.

## How It Works

The following is high level sequence diagram on how k6 and Tracetest interact with the different pieces of the system.

```mermaid
sequenceDiagram
    k6->>+Extension: Trigger HTTP Request
    Extension->>+Extension: Generate Trace ID and propagation headers
    Extension->>+Instrumented Service: Sends request with tracing metadata
    Instrumented Service->>+Data Store: Sends Telemetry data
    Instrumented Service-->>-Extension: Returns Response
    Extension->>+Tracetest Agent: Executes the test run using the trace id
    Tracetest Agent->>+Data Store: Fetches trace using the trace id
    Data Store-->>-Tracetest Agent: Returns trace
    Tracetest Agent->>+Tracetest: Sync and store trace in Tracetest
    Tracetest->>+Tracetest: Runs Assertions against the resulted trace
    Tracetest->>+Tracetest Agent: Return Assertion results
    Tracetest Agent-->>-Extension: Returns the run results
    Extension-->>-k6: Display summary and results
```

## Today You'll Learn About Performance & Trace-Based Tests

This is a simple quick start guide on how to run the Tracetest k6 extension to run enhanced performance tests with trace-based testing. The infrastructure will use the Pokeshop Demo as a testing ground, triggering requests against it and generating telemetry data.

## Requirements

**Tracetest Account**:

- Sign up to [`app.tracetest.io`](https://app.tracetest.io) or follow the [get started](/getting-started/overview) docs.
- Create an [environment](/concepts/environments).
- Create an [environment token](/concepts/environment-tokens).
- Have access to the environment's [agent API key](/configuration/agent).

**Docker**:

- Have [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed on your machine.

## Run This Quckstart Example

Clone the official [Tracetest Pokeshop Demo App Repo](https://github.com/kubeshop/pokeshop) to your local machine.

```bash
git clone https://github.com/kubeshop/pokeshop.git
cd pokeshop
```

Follow these instructions to run the Cypress example:

1. Copy the `.env.template` file to `.env`.
2. Log into the [Tracetest app](https://app.tracetest.io/).
3. This example is configured to use Jaeger. Ensure the environment you will be utilizing to run this example is also configured to use the Jaeger Tracing Backend by clicking on Settings, Tracing Backend, Jaeger, updating the URL to `jaeger:16685`, Test Connection and Save.
4. Fill out the [token](https://docs.tracetest.io/concepts/environment-tokens) and [agent API key](https://docs.tracetest.io/concepts/agent) details by editing your `.env` file. You can find these values in the Settings area for your environment.
5. Change the `POKESHOP_DEMO_URL` to `http://api:8081` in the `.env` file.
6. Run `docker compose -f docker-compose.yml -f docker-compose.k6.yml run k6-tracetest`.

Follow along with the sections below for an in detail breakdown of what the example you just ran did and how it works.

## Project Structure

The project is built with Docker Compose.

### Pokeshop Demo App

The [Pokeshop Demo App](/live-examples/pokeshop/overview) is a complete example of a distributed application using different backend and front-end services, implementation code is written in Typescript.

The `docker-compose.yml` file in the root directory is for the Pokeshop Demo app and the OpenTelemetry setup.
And the `docker-compose.k6.yml` includes the [Tracetest Agent](/concepts/agent) and the K6 Load Tests.

Finally, the k6 load tests can be found in `test/k6/import-pokemon.js`.

## Installing the k6 Tracetest Extension

[Installing the k6 Tracetest extension](https://github.com/grafana/xk6) is as easy as running the following command:

<Tabs groupId="k6">
  <TabItem value="Linux" label="Linux" default>

```bash title="Terminal"
docker run --rm -it -u "$(id -u):$(id -g)" -v "${PWD}:/xk6" \
  grafana/xk6 build v0.43.1 \
  --with github.com/kubeshop/xk6-tracetest
```

  </TabItem>

  <TabItem value="MacOS" label="MacOS" default>

```bash title="Terminal"
docker run --rm -it -e GOOS=darwin -u "$(id -u):$(id -g)" -v "${PWD}:/xk6" \
  grafana/xk6 build v0.43.1 \
  --with github.com/kubeshop/xk6-tracetest
```

  </TabItem>

  <TabItem value="Windows" label="Windows" default>

```bash title="Terminal"
docker run --rm -it -e GOOS=windows -u "$(id -u):$(id -g)" -v "${PWD}:/xk6" `
  grafana/xk6 build v0.43.1 --output k6.exe `
  --with github.com/kubeshop/xk6-tracetest
```

  </TabItem>
</Tabs>

This will generate the `k6-tracetest` binary in the current directory.

The instructions can be also found in the main [k6 docs](https://k6.io/docs/extensions/get-started/bundle/) in case you need to combine multiple extensions into one binary.

## Using the Tracetest Extension For Load Tests

Once you have installed the k6 Tracetest binary, you can use the base k6 functionality to run load tests against instrumented services and Tracetest to run checks against the resulting telemetry data.

## Creating Your k6 Script

The `test/k6/import-pokemon.js` file contains the k6 script that will be used to run the performance tests. It is a simple script that will trigger a `POST` request to the `/pokemon/import` Pokeshop Demo app endpoint.

```javascript
import { Http, Tracetest } from 'k6/x/tracetest';
import { sleep } from 'k6';

export const options = {
  vus: 1,
  duration: '5s',
};

const POKESHOP_DEMO_URL = __ENV.POKESHOP_DEMO_URL || 'http://localhost:8081';

const http = new Http();
const tracetest = Tracetest();

let pokemonId = 6; // charizard

export default function () {
  const url = `${POKESHOP_DEMO_URL}/pokemon/import`;
  const payload = JSON.stringify({
    id: pokemonId++,
  });
  const params = {
    headers: {
      'Content-Type': 'application/json',
    },
  };

// tracetest test definition
  const definition = `type: Test
spec:
  id: k6-tracetest-pokeshop-import-pokemon
  name: K6
  description: K6
  trigger:
    type: k6
  specs:
    - selector: span[tracetest.span.type="general" name="import pokemon"]
      name: Should have imported the pokemon
      assertions:
        - attr:tracetest.selected_spans.count = 1
    - selector: |-
        span[tracetest.span.type="http" net.peer.name="pokeapi.co" http.method="GET"]
      name: Should trigger a request to the POKEAPI
      assertions:
        - attr:http.url   =  "https://pokeapi.co/api/v2/pokemon/${pokemonId}"
`;

  const response = http.post(url, payload, params);

  tracetest.runTest(
    response.trace_id,
    {
      definition,
      should_wait: true,
    },
    {
      url,
      method: 'GET',
    }
  );

  sleep(1);
}

export function handleSummary() {
  return {
    stdout: tracetest.summary(),
  };
}

export function teardown() {
  tracetest.validateResult();
}
```

### Setting the Environment Variables

Copy the `.env.template` content into a new `.env` file.

```bash title=Terminal
cp .env.template .env
```

Add the [Tracetest API Token](/concepts/environment-tokens) and [Tracetest Agent API Key](/configuration/agent) to the `TRACETEST_API_TOKEN` and `TRACETEST_AGENT_API_KEY` variables.

```bash title=.env
TRACETEST_API_TOKEN=<YOUR_API_TOKEN> # your environment token
TRACETEST_AGENT_API_KEY=<YOUR_AGENT_API_KEY>
POKESHOP_DEMO_URL=http://api:8081
```

### Starting the Pokeshop Demo App

Having the full setup ready, the final step is to run the k6 script. To do that, run the following command:

```bash
docker compose -f docker-compose.yml -f docker-compose.k6.yml run k6-tracetest
WARN[0000] The "TRACETEST_SERVER_URL" variable is not set. Defaulting to a blank string.
[+] Creating 9/9
 ✔ Network pokeshop_default              Created                                                                                                                  0.0s
 ✔ Container pokeshop-jaeger-1           Created                                                                                                                  0.1s
 ✔ Container pokeshop-db-1               Created                                                                                                                  0.1s
 ✔ Container pokeshop-cache-1            Created                                                                                                                  0.1s
 ✔ Container pokeshop-queue-1            Created                                                                                                                  0.1s
 ✔ Container pokeshop-tracetest-agent-1  Created                                                                                                                  0.1s
 ✔ Container pokeshop-otel-collector-1   Created                                                                                                                  0.1s
 ✔ Container pokeshop-worker-1           Created                                                                                                                  0.1s
 ✔ Container pokeshop-api-1              Created                                                                                                                  0.1s
[+] Running 8/8
 ✔ Container pokeshop-queue-1            Healthy                                                                                                                  7.7s
 ✔ Container pokeshop-cache-1            Healthy                                                                                                                  2.7s
 ✔ Container pokeshop-db-1               Healthy                                                                                                                  2.7s
 ✔ Container pokeshop-tracetest-agent-1  Started                                                                                                                  0.5s
 ✔ Container pokeshop-jaeger-1           Healthy                                                                                                                  2.1s
 ✔ Container pokeshop-otel-collector-1   Started                                                                                                                  0.1s
 ✔ Container pokeshop-api-1              Started                                                                                                                  0.2s
 ✔ Container pokeshop-worker-1           Started                                                                                                                  0.1s

          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: /import-pokemon.js
        output: xk6-tracetest-output (TestRunID: 53770)

     scenarios: (100.00%) 1 scenario, 1 max VUs, 35s max duration (incl. graceful stop):
              * default: 1 looping VUs for 5s (gracefulStop: 30s)

```

:::tip View these tests in our Demo environment
[👉 Join our shared Pokeshop API Demo environment.](https://app.tracetest.io/organizations/ttorg_2179a9cd8ba8dfa5/invites/invite_760904a64b4b9dc9/accept)
:::

## What's Next?

After running the initial set of tests, you can click the run link for any of them, update the assertions and run the scripts once more. This flow enables complete a trace-based TDD flow.

![assertions](./img/tracetest-cloud-k6-resize.gif)

## Learn More

Please visit our [examples in GitHub](https://github.com/kubeshop/tracetest/tree/main/examples) and join our [Slack Community](https://dub.sh/tracetest-community) for more info!
